<?php

require_once "PageClass.inc" ;
require_once "define.inc" ;

class PageTask extends ProjectPage
{
    protected $_row ;

    public function __construct($projectid,
                                $pagecode, 
                                $taskcode) {
        global $DpDb;
        global $User;

        $this->_projectid = $projectid;
        $this->_pagecode  = $pagecode;

        // username for userqual join
        $username = $User->UserName();

        $sql = "-- PageTask
            SELECT
                pt.pagetaskid,
                pt.projectid,
                pt.pagecode,
                pt.taskcode,
                p.nameofwork,
                p.language,
                p.chartableurl,
                p.is_unicode,
                pp.imagefilename,
                t.helpUrl AS task_help_url,
                t.instructionsurl AS task_url,
                t.caption AS taskcaption,
                t.description AS TaskDescription,
                pt.sequencenumber,
                pt.username,
                pt.checkouttime,
                pt.completiontime,
                pv.versionnumber AS maxversionnumber,
                pvnext.createtime AS nextversiontime,
                pvnext.taskcode AS nexttaskcode, -- taskcode for next version if any
                pvnext.username AS nextusername,
                pvnext.versionnumber AS nextversionnumber,
                uq.qualcode,
                t.tasktype
            FROM
                pagetasks AS pt

            JOIN
                projects AS p
            ON
                pt.projectid = p.projectid

            JOIN
                pages AS pp
            ON
                pt.projectid = pp.projectid
                AND pt.pagecode = pp.pagecode

            JOIN
                tasks AS t
            ON
                pt.taskcode = t.taskcode


            LEFT JOIN
                pageversions AS pv
            ON
                pt.projectid = pv.projectid
                AND pt.pagecode = pv.pagecode
                AND pt.taskcode = pv.taskcode

            LEFT JOIN
                pageversions AS pvnext
            ON
                pv.projectid = pvnext.projectid
                AND pv.pagecode = pvnext.pagecode
                AND pv.versionnumber < pvnext.versionnumber
                AND NOT EXISTS 
                (   SELECT 1 FROM pageversions
                    WHERE projectid = pv.projectid
                    AND pagecode = pv.pagecode
                    AND versionnumber > pv.versionnumber
                    AND versionnumber < pvnext.versionnumber
                )

            LEFT JOIN
                userquals AS uq
            ON
                t.tasktype = 'A'
                OR (
                    pt.taskcode = uq.qualcode
                    AND uq.username = '$username'
                )

            WHERE
                pt.projectid = '$projectid'
                AND pt.pagecode = '$pagecode'
                AND pt.taskcode = '$taskcode'

            ORDER BY
                pv.versionnumber

            LIMIT 1\n";

        $this->_row = $DpDb->SqlOneObject( $sql ) ;
        $this->_imagefilename = $this->_row->imagefilename ;
        // var_dump($this);
    }

    public function SaveText( $text ) {
        require_once "PageVersionClass.inc" ;
        global $Context;

        if( ! $this->UserIsOwner() ) {
            $vno = $this->MaxVersionNumber() ;
            $vsn = new PageVersion( $this, $vno ) ;
        }
         else {
            $vsn = new PageVersion( $this ) ;
            $vno = $this->MaxVersionNumber() + 1 ;
        }

        $vsn->SaveText( $text ) ;

        $this->SetCompletion() ;

        $Context->LogEvent($this->ProjectId(),
                           $this->PageCode(),
                           $vno,
                           $this->TaskCode(),
                           EVENT_SAVE);
    }

    public function SetCompletion() {
        global $User ;
        global $DpDb ;

        $username   = $User->UserName() ;
        $id         = $this->PageTaskId() ;
        $sql = "UPDATE
                    pagetasks
                SET
                    completiontime = UNIX_TIMESTAMP(),
                    username = '$username'
                WHERE
                    pagetaskid = $id";
        $i = $DpDb->SqlExecute($sql);
        assert($i == 1);
    }

    /*
    public function TempPageText() {
    }
    */

    public function VersionPageText( $verno ) {
        return $this->PageVersion($verno)->PageText() ;
    }

    public function PageVersion( $verno ) {
        require_once "PageVersionClass.inc" ;
        return new PageVersion( $this, $verno ) ;
    }

    /*
    public function PageVersionId() {
        return $this->_row->pageversionid ;
    }
    */

    public function PageTaskId() {
        return $this->_row->pagetaskid ;
    }

    public function TaskCode() {
        return $this->_row->taskcode ;
    }

    public function UserName() {
        return $this->_row->username ;
    }

    public function NextPageTask() {
        $ntc = $this->Next() ;
        if( empty( $ntc ) ) {
            return null ;
        }
        return new PageTask( $this->ProjectId(),
                             $this->PageCode(),
                             $ntc ) ;
    }

    // return a pagetask for the next available page
    public function CheckOutNextPage() {
        
    }

    public function NextUserName() {
        return $this->_row->nextusername ;
    }

    public function NextVersionTime() {
        return $this->_row->nextversiontime ;
    }

    public function NextTaskCode() {
        return $this->_row->nexttaskcode ;
    }

    public function TaskDescription() {
        return $this->_row->TaskDescription ;
    }

    public function HelpUrl() {
        return $this->_row->task_help_url ;
    }

    public function TaskUrl() {
        return $this->_row->task_url ;
    }

    public function MaxVersionNumber() {
        return $this->_row->maxversionnumber ;
    }

    public function TaskCaption() {
        return $this->_row->taskcaption ;
    }

    public function EditLink() {
        $url = $this->TaskUrl();
        $caption = $this->TaskCaption();
        return "<a href='$url'>$caption</a>";
    }

    public function HelpLink() {
        $helpurl = $this->TaskHelpUrl();
        $caption = $this->TaskCaption();
        return "<a href='$helpurl'>$caption Help</a>";
    }

    public function CheckedOutBy() {
        return $this->_row->checked_out_by ;
    }

    public function CheckedOutTime() {
        return $this->_row->checked_out_time ;
    }

    public function CheckedInTime() {
        return $this->_row->checked_in_time ;
    }

    public function MinutesWhileCheckedOut() {
        $out = $this->CheckedOutTime();
        $in = $this->CheckedInTime();
        if(empty($out) || empty($in)) {
            return null;
        }
        return DpMinutes($in - $out);
    }

    public function MinutesSinceCheckedOut() {
        $out = $this->CheckedOutTime();
        $in = $this->CheckedInTime();

        if(empty($out) || (! empty($in))) {
            return null;
        }
        else {
            return DpMinutesAgo($this->checkedOutTime());
        }
    }

    private function _is_user_qual() {
        return ! empty( $this->_row->userqual ) ;
    }

    private function _task_type() { 
        return $this->_row->tasktype ;
    }

    public function UserMayDoMe() {
        global $User;
        $user = $this->UserName();
        // either user owns this, or no one does;
        // and user has matching qual.
        if( ! $this->_is_user_qual() && $this->_task_type != "A" )
            return false;
        if( $user == $User->UserName() )
            return true;
        if(empty($user))
            return true;
        return false;
    }

    public function CheckOut() {
        global $User ;
        global $DpDb;
        global $Context;

        $username = $User->UserName();
        $pagetaskid = $this->PageTaskId() ;

        $sql = "UPDATE pagetasks
                SET username = '$username',
                    checkouttime = UNIX_TIMESTAMP()
                WHERE pagetaskid = $pagetaskid" ; 
        assert($DpDb->SqlExecute($sql) > 0 ) ;
                    
        $Context->LogEvent($this->ProjectId(),
                           $this->PageCode(),
                           $this->PageTaskid(),
                           EVENT_CHECK_OUT);
    }

    private function isVersion() {
        return $this->MaxVersionNumber() > 0 ;
    }

    public function UnCheckOut() {
        global $Context;
        global $DpDb;

        if( ! $this->UserIsOwner() ) {
            return ;
        }
        $id = $this->PageTaskId() ;
        $Context->LogEvent($this->ProjectId(),
                            $this->PageCode(),
                            $this->TaskCode(),
                            null,
                            EVENT_UNCHECK_OUT);
        $sql = "UPDATE pagetasks
                SET username = NULL,
                    checkouttime = NULL,
                    completiontime = NULL
                WHERE
                    projectid = '{$this->ProjectId()}'
                    AND pagecode = '{$this->PageCode()}'
                    AND taskcode = '{$this->TaskCode()}'";
        $DpDb->SqlExecute($sql) ;
        
        require_once "PageVersionClass.inc" ;
        $pv = new PageVersion( $this, $this->MaxVersionNumber() ) ;
        assert( $this->ProjectId() == $pv->ProjectId() ) ;
        assert( $this->PageCode() == $pv->PageCode() ) ;
        assert( $this->TaskCode() == $pv->TaskCode() ) ;
        $pv->Delete() ;
    }
}

/*
class PageTasks
{
    protected $_items = array();
    protected $_projectid ;

    function __construct($projectid)
    {
        global $DpDb;
        $this->_projectid = $projectid;
        $sql = "-- PageTasks
                    SELECT
                    pt.pagetaskid,
                    pt.projectid,
                    pt.pagecode,
                    pt.taskcode,
                    pt.sequencenumber,
                    pt.username,
                    pt.checkouttime,
                    pt.completiontime,
                    pv.maxversionnumber,
                    t.helpurl AS task_help_url,
                    t.instructionsurl AS task_url,
                    t.caption AS taskcaption,
                    t.description AS oaskdescription
                FROM
                    pagetasks AS pt
                    

                JOIN
                    tasks AS t
                ON
                    pt.taskcode = t.taskcode
                

                LEFT JOIN
                    pageversions AS pv
                ON
                    pt.pagetaskid= pv.pagetaskid
               

                WHERE
                    pt.projectid = '$projectid'

                ORDER BY
                    

        $rows = $DpDb->SqlObjects( $sql ) ;
        foreach($rows as $row)
        {
            $pt = new PageTask($projectid, $row->pagecode, $row->taskcode);
            $this->_items[$row->pagecode] = $pt ;
        }
    }

    public function Items() {
        return $this->_items ;
    }

    public function TaskDescription() {
        return $this->_row->taskdescription ;
    }
}

class UserTasks extends PageTasks
{
    function __construct( $projectid ) {
        global $DpDb ;
        global $User ;

        $username = $User->UserName() ;
        $this->_projectid = $projectid ;

        $sql = "-- UserTasks
                    SELECT
                    pt.pagetaskid,
                    pt.projectid,
                    pt.pagecode,
                    pt.taskcode,
                    pt.sequencenumber,
                    pt.username,
                    pt.checkouttime,
                    pt.completiontime,
                    pv.versionnumber,
                    ptnext.taskcode AS nexttaskcode,
                    ptnext.username AS nextusername,
                    ptnext.checkouttime AS nextcheckouttime,
                    ptnext.completiontime AS nextcompletiontime,
                    pvnext.versionnumber AS nextversionnumber,
                    t.helpurl AS task_help_url,
                    t.instructionsurl AS task_url,
                    t.caption AS taskcaption,
                    t.description AS oaskdescription,
                    ptnext.pagetaskid AS ptnextid
                FROM
                    pagetasks pt


                JOIN
                    tasks t
                ON
                    pt.taskcode = t.taskcode


                LEFT JOIN
                    pageversions pv
                ON
                    pt.projectid = pv.projectid
                    AND pt.pagecode = pv.pagecode
                    AND pt.taskcode = pv.taskcode


                LEFT JOIN
                    pageversions pvnext
                ON
                    pv.projectid = pvnext.projectid
                    AND pv.pagecode = pvnext.pagecode
                    AND pv.versionnumber < pvnext.versionnumber
                    AND NOT EXISTS 
                    (   SELECT 1 FROM pageversions
                        WHERE projectid = pv.projectid
                        AND pagecode = pv.pagecode
                        AND versionnumber > pv.versionnumber
                        AND versionnumber < pvnext.versionnumber
                    )

                LEFT JOIN
                    pagetasks AS ptnext
                ON
                    pvnext.pagetaskid = ptnext.pagetaskid

                WHERE
                    pt.projectid = '$projectid'
                    AND pt.username = '$username'";
        // die( PrettySql( $sql ) ) ;
        $rows = $DpDb->SqlObjects( $sql ) ;
        foreach($rows as $row) {
            $pt = new PageTask($projectid, $row->pagecode, $row->taskcode);
            $this->_items[$row->pagecode] = $pt ;
        }
    }

    function TaskCode() {
        return $this->_items->taskcode ;
    }
}
*/

class Tasks
{
    private $_items ;

    function __construct() {
        global $DpDb;
        $sql = "SELECT * FROM tasks
                ORDER BY sequencenumber";
        $trows = $DpDb->SqlObjects($sql);
        $this->_items = array() ;
        foreach( $trows as $r )
        {
            $this->_items[$r->taskcode] = $r;
        }
    }

    public function Items() {
        return $this->_items;
    }
}

class Task
{
    private $_row;

    function __construct($arg) {
        global $DpDb;
        if(is_array($arg))
            $this->_row = $arg;
        else
            $this->_row = $DpDb->SqlOneObject("SELECT * FROM tasks");
    }

    public function TaskCode() {
        return $this->_row->taskcode ;
    }

    public function Description() {
        return empty($this->_row) 
                    ? ""
                    : $this->_row->description;
    }

    public function Caption() {
        return $this->_row->taskcaption;
    }

    public function Url() {
        return $this->_row->task_url;
    }

    public function HelpUrl() {
        return $this->_row->task_help_url;
    }

    public function GoalToday() {
        return $this->_row->goal_today;
    }

    public function GoalYesterday() {
        return $this->_row->goal_yesterday;
    }

    public function GoalMonth() {
        return $this->_row->goal_month;
    }

    public function TotalToday() {
        return $this->_row->goal_today;
    }

    public function TotalYesterday() {
        return $this->_row->goal_yesterday;
    }

    public function TotalMonth() {
        return $this->_row->total_month;
    }
}

class ProjectPageTasks
{
    protected   $_projectid;
    protected   $_project_pages = array();
    protected   $_exists = false ;

    public function rojectPages($projectid) {
        global $DpDb;

        $this->_projectid = $projectid;
        !empty($projectid)
            or die("ProjectPages with null projectid.");
        $rows = SqlProjectPages( $projectid ) ;

        if( count( $rows ) == 0 ) {
            return ;
        }

        $this->_exists = true ;
        foreach($rows as $row) {
            $code = $row->pagecode;
            $this->_project_pages[$code] = new RowPage($row) ;
        }
        assert(count($this->_project_pages) == count($rows));
    }

    public function ProjectId() {
        return $this->_projectid;
    }

    public function Exists() {
        return $this->_exists;
    }

    public function Rows() {
        return $this->_project_pages;
    }

    public function ProjectPath() {
        return ProjectPath($this->_row->_projectid);
    }

    public function Page($pagecode) {
        assert(! empty( $pagecode ) ) ;
        $pg = @$this->_project_pages[$pagecode];
        return empty( $pg ) ? null : $pg ;
    }

    public function AddFromFilesets(&$sets) {
        foreach($sets as $set) {
            $this->AddFromFileset($set);
        }
    }

    public function AddFromFileset(&$set) {
        $projectid      = $this->ProjectId();
        $pagecode       = $set->PageCode();
        $imagename      = $set->ImageFileName();
        $textpath       = $set->TextFilePath();
        $imagepath      = $set->ImageFilePath();

        $pg = new ProtoPage($projectid, $pagecode, $imagename);
        $pg->InitTextFromPath($textpath);
        $pg->InitImageFromPath($imagepath);
        $this->_project_pages[$pagecode] = $pg;
        $this->AddPageRecord($projectid, $pagecode, $imagename);
    }

    public function AddPageRecord($projectid, $pagecode, $imagefilename) {
        global $DpDb;
        $sql = "REPLACE INTO pages
                (   projectid,
                    pagecode,
                    imageFileName
                ) VALUES
                ('  '$projectid',
                    '$pagecode',
                    '$imagefilename'
                )";
        $i = $DpDb->SqlExecute($sql);
    }

    public function MakeThumbnails() {
        foreach($this->_project_pages as $pg) {
            $pg->MakeThumbnail(true);
        }
    }
    
    public function Count() {
        return count($this->_project_pages);
    }
    
    public function DeleteAll() {
        global $DpDb;

        $sql = "DELETE FROM pages
                WHERE projectId = '{$this->ProjectId()}'";
        $DpDb->SqlExecute($sql);
    }
}

function SqlProjectPageTasks($projectid) {
    global $DpDb ;
    $sql = "SELECT
                p.nameofwork,
                p.authorsname,
                p.chartableurl,
                p.is_unicode,
                pp.projectid,
                pp.pagecode,
                pp.imagefilename,
                pt.taskcode,
                pt.username,
                pt.completiontime,
                pt.checkouttime,
                COALESCE(pt.completiontime,
                         pt.checkouttime) AS tasktime,
                CASE WHEN EXISTS
                (   SELECT 1 FROM pagetasks AS ptdiff
                    WHERE projectid = pt.projectid 
                        AND pagecode = pt.pagecode
                        AND completiontime > pt.completiontime
                        AND NOT completiontime IS NULL
                ) THEN 1 ELSE 0 END AS isdiff
            FROM
                pages AS pp
            JOIN
                projects AS p
            ON
                pp.projectid = p.projectid
            LEFT JOIN
                pagetasks AS pt
            ON
                pp.projectid = pt.projectid
                AND pp.pagecode = pt.pagecode
                AND pt.username IS NOT NULL
            LEFT JOIN
                tasks as t
            ON
                pt.taskcode = t.taskcode
            WHERE
                pp.projectid = '$projectid'
            ORDER BY
                pp.pagecode,
                pt.sequencenumber";
    // die( PrettySql( $sql ) ) ;
    return $DpDb->SqlObjects( $sql ) ;
}


?>
